package org.dromara.common.core.utils;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * @author CKJ
 * @description: 计算距离
 * @date 2025/7/6 17:43
 */
public class PositionUtil {

    /**
     * 高德地图计算方法
     *
     * @param longitude1 第一点的经度
     * @param latitude1  第一点的纬度
     * @param longitude2 第二点的经度
     * @param latitude2  第二点的纬度
     * @return 返回的距离，单位m
     */
    public static Double getDistance(String longitude1, String latitude1, String longitude2, String latitude2) {
        // 参数校验
        if (longitude1 == null || latitude1 == null || longitude2 == null || latitude2 == null) {
            return -1.0;
        }

        // 转换为double并校验有效性
        double lon1 = Double.parseDouble(longitude1);
        double lat1 = Double.parseDouble(latitude1);
        double lon2 = Double.parseDouble(longitude2);
        double lat2 = Double.parseDouble(latitude2);

        // 检查是否为有效坐标范围
        if (!isValidCoordinate(lon1, lat1) || !isValidCoordinate(lon2, lat2)) {
            return -1.0;
        }

        lon1 *= 0.01745329251994329;
        lat1 *= 0.01745329251994329;
        lon2 *= 0.01745329251994329;
        lat2 *= 0.01745329251994329;
        double var1 = Math.sin(lon1);
        double var2 = Math.sin(lat1);
        double var3 = Math.cos(lon1);
        double var4 = Math.cos(lat1);
        double var5 = Math.sin(lon2);
        double var6 = Math.sin(lat2);
        double var7 = Math.cos(lon2);
        double var8 = Math.cos(lat2);
        double[] var10 = new double[3];
        double[] var20 = new double[3];
        var10[0] = var4 * var3;
        var10[1] = var4 * var1;
        var10[2] = var2;
        var20[0] = var8 * var7;
        var20[1] = var8 * var5;
        var20[2] = var6;
        double distance= Math.asin(Math.sqrt((var10[0] - var20[0]) * (var10[0] - var20[0]) + (var10[1] - var20[1]) * (var10[1] - var20[1]) + (var10[2] - var20[2]) * (var10[2] - var20[2])) / 2.0) * 1.27420015798544E7;
        // 结果四舍五入 保留2位小数
        return new BigDecimal(distance).setScale(2, RoundingMode.HALF_UP).doubleValue();
    }

    /**
     * 校验坐标是否有效
     * @param lon 经度 (-180 to 180)
     * @param lat 纬度 (-90 to 90)
     * @return 是否有效
     */
    private static boolean isValidCoordinate(double lon, double lat) {
        return lon >= -180 && lon <= 180 && lat >= -90 && lat <= 90;
    }

}
